package com.example.javabasic.spring.proxy.demo2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

//动态代理

/**
 *  是一种利用jdk的反射机制,创建java对象的能力,创建的是代理类的对象,而不用创建类文件,不用写java文件
 * 介绍:
 * 1.代理对象,不需要实现接口
 * 2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
 * 3.动态代理也叫做:JDK代理,接口代理
 * 原理:
 * 利用反射机制生成一个实现代理接口的匿名类，在调用具体方法前调用InvokeHandler来处理
 * cglib动态代理： 利用asm开源包，对代理对象类的class文件加载进来，通过修改其字节码生成子类来处理。
 * JDK动态代理只能对实现了接口的类生成代理，而不能针对类
 * 适用场景：
 * CGLIB是针对类实现代理，主要是对指定的类生成一个子类，覆盖其中的方法 因为是继承，所以该类或方法不要声明成final
 * 如果目标对象实现了接口，默认情况下会采用JDK的动态代理实现AOP
 * 如果目标对象实现了接口，可以强制使用CGLIB实现AOP
 * 如果目标对象没有实现了接口，必须采用CGLIB库，spring会自动在JDK动态代理和CGLIB之间转换
 * 如何强制使用CGLIB实现AOP：
 * 1、添加CGLIB库，SPRING_HOME/cglib/*.jar
 * 2、在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>
 */
public class Test {
    public static void main(String[] args) {
//        System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        //创建目标类对象
        CustomProxy proxy = new CustomProxyImpl1();
        //创建一个handler对象
        InvocationHandler handler = new ProxyHandler(proxy);
        //创建代理对象, 用Proxy , 传入参数为  类加载器, 目标对象,invocationHandler 实现类,    调用结果转为接口类型
        CustomProxy o = (CustomProxy) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), proxy.getClass().getInterfaces(), handler);
        //执行代理方法
        System.out.println("result->"+o);
        o.sayHello();
    }
}
